/**
 * 语音录制工具类
 * 用于录制、保存并转换语音文件
 */

class AudioRecorder {
  constructor() {
    this.mediaRecorder = null;
    this.audioChunks = [];
    this.stream = null;
    this.isRecording = false;
    this.startTime = null;
    this.maxDuration = 60000; // 默认最大录制时长为60秒
  }

  /**
   * 请求麦克风权限并开始录音
   * @param {number} maxDuration - 最大录制时长（毫秒），默认60秒
   * @returns {Promise<void>}
   */
  async startRecording(maxDuration = 60000) {
    try {
      this.maxDuration = maxDuration;
      this.audioChunks = [];
      
      // 请求麦克风权限
      this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      
      // 创建媒体录制器
      this.mediaRecorder = new MediaRecorder(this.stream);
      
      // 监听数据可用事件
      this.mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          this.audioChunks.push(event.data);
        }
      };
      
      // 开始录制
      this.mediaRecorder.start();
      this.isRecording = true;
      this.startTime = Date.now();
      
      // 设置自动停止计时器
      this.autoStopTimer = setTimeout(() => {
        if (this.isRecording) {
          this.stopRecording();
        }
      }, this.maxDuration);
      
      console.log('开始录音...');
    } catch (error) {
      console.error('获取麦克风权限失败:', error);
      throw new Error('无法获取麦克风权限，请确保已授予麦克风访问权限');
    }
  }

  /**
   * 停止录音并返回录音数据
   * @returns {Promise<{blob: Blob, duration: number}>} 录音Blob对象和持续时间(秒)
   */
  stopRecording() {
    return new Promise((resolve, reject) => {
      if (!this.isRecording || !this.mediaRecorder) {
        reject(new Error('没有正在进行的录音'));
        return;
      }
      
      // 清除自动停止计时器
      if (this.autoStopTimer) {
        clearTimeout(this.autoStopTimer);
      }
      
      // 计算录音持续时间（毫秒）
      const duration = Date.now() - this.startTime;
      
      // 监听录制停止事件
      this.mediaRecorder.onstop = () => {
        // 关闭媒体流
        if (this.stream) {
          this.stream.getTracks().forEach(track => track.stop());
        }
        
        // 创建音频Blob对象
        const audioBlob = new Blob(this.audioChunks, { type: 'audio/mpeg' });
        
        // 清理状态
        this.isRecording = false;
        this.mediaRecorder = null;
        this.stream = null;
        
        // 返回录音数据和持续时间
        resolve({
          blob: audioBlob,
          duration: Math.round(duration / 1000) // 转换为秒
        });
        
        console.log('录音完成，持续时间:', Math.round(duration / 1000), '秒');
      };
      
      // 停止录制
      this.mediaRecorder.stop();
    });
  }

  /**
   * 取消录音
   */
  cancelRecording() {
    if (!this.isRecording) {
      return;
    }
    
    // 清除自动停止计时器
    if (this.autoStopTimer) {
      clearTimeout(this.autoStopTimer);
    }
    
    // 停止录制
    if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
      this.mediaRecorder.stop();
    }
    
    // 关闭媒体流
    if (this.stream) {
      this.stream.getTracks().forEach(track => track.stop());
    }
    
    // 清理状态
    this.isRecording = false;
    this.mediaRecorder = null;
    this.stream = null;
    this.audioChunks = [];
    
    console.log('录音已取消');
  }

  /**
   * 将Blob转换为File对象
   * @param {Blob} blob - 音频Blob对象
   * @param {number} duration - 录音持续时间(秒)
   * @returns {File} 文件对象
   */
  createAudioFile(blob, duration) {
    // 创建文件名
    const fileName = `voice_message_${Date.now()}.mp3`;
    
    // 创建File对象，包含duration元数据
    const file = new File([blob], fileName, { 
      type: 'audio/mpeg',
      lastModified: Date.now()
    });
    
    // 添加自定义属性
    file.duration = duration;
    
    return file;
  }

  /**
   * 创建音频预览URL
   * @param {Blob} blob - 音频Blob对象
   * @returns {string} 预览URL
   */
  createAudioPreviewUrl(blob) {
    return URL.createObjectURL(blob);
  }
}

// 导出单例实例
export default new AudioRecorder(); 